/**
 * @file fileTransferCmds.c
 * @author MTF-1
 *
 * @date 22-01-2011 DD-MM-YYYY
 * @version 0.6
 *
 * @section DESCRIPTION
 *
 * Module for file transfer commands.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "connectionCmds.h"
#include "fileTransferCmds.h"

#define ERROR 1
#define NOERROR 0
#define UP_RCVBUFLEN 10
#define UP_SNDBUFLEN 1460
#define UP_CMDSNDBUFLEN 155
#define DOWN_RCVBUFLEN 1460
#define DOWN_CMDSNDBUFLEN 155

/**
 * Upload a specified file on the client under a specified name to the server.
 *
 * @param ptr_sFilenameClient name of the file located on the client.
 * @param ptr_sFilenameServer name of the file located on the server.
 * @return 1 on error (failed to upload) and 0 on no error.
 * @author Rik Janssen, Robbert Busser
 */
int cmdUpload(char *ptr_sFilenameClient, char *ptr_sFilenameServer)
{
    char sRecvBuf[UP_RCVBUFLEN];
    char sCmdSndBuf[UP_CMDSNDBUFLEN] = "UPLOAD ";
    char sSendBuf[UP_SNDBUFLEN];
    int i, iInFileFD = 0, iBytesRcvd = 0, iBytesRead = 0, iBytesSend = 0;

    /*Open file*/
    printf("Opening file %s...\n", ptr_sFilenameClient);
    if((iInFileFD = open(ptr_sFilenameClient, O_RDONLY)) == -1)
    {
        perror("Error: can't open file.\n");
        return ERROR;
    }

    if(chkConnection())
    {
        fprintf(stderr, "Error: there's currently no active connection.\n");
        close(iInFileFD);
        return ERROR;
    }

    /*Empty receive buffer*/
    for(i=0; i<UP_RCVBUFLEN; i++)
    {
        sRecvBuf[i] = 0;
    }

    /*Send UPLOAD command*/
    strcat(sCmdSndBuf, ptr_sFilenameServer);
    if(send(iSocketFD, &sCmdSndBuf, strlen(sCmdSndBuf)+1, 0) == -1)
    {
        perror("Error: failed to send \"UPLOAD\" command.\n");
        close(iInFileFD);
        return ERROR;
    }

    /*Receive return message from server*/
    if((iBytesRcvd = recv(iSocketFD, &sRecvBuf, UP_RCVBUFLEN-1, 0)) <= 0)
    {
        perror("Error: failed to receive upload confirmation from the server.\n");
        close(iInFileFD);
        return ERROR;
    }

    sRecvBuf[iBytesRcvd] = '\0'; /*Terminate the received message*/

    /*Check the received message*/
    if(!strcasecmp(sRecvBuf, "READY"))
    {
        printf("Uploading %s under %s to %s...\n", ptr_sFilenameClient, ptr_sFilenameServer, sServerName);

        /*Begin reading file*/
        while((iBytesRead = read(iInFileFD, &sSendBuf, UP_SNDBUFLEN)) > 0)
        {
            /*Send number of bytes read to server and check if server sends all bytes*/
           while((iBytesSend = send(iSocketFD, &sSendBuf, iBytesRead, 0)) != iBytesRead)
           {
               /*Check if sending goes well*/
               if(iBytesSend == -1)
               {
                   perror("Error: failed to send data to server.\n");
                   close(iInFileFD);
                   return ERROR;
               }
           }
        }

        /*Reading of file complete -> close file and check if read completed corectly*/
        close(iInFileFD);
        if(iBytesRead == -1)
        {
            fprintf(stderr, "Error: read error on file during data transfer.\n");
            return ERROR;
        }

        printf("Done!\n");
    }
    if(!strcasecmp(sRecvBuf, "ERROR"))
    {
        fprintf(stderr, "Error: file already exists.\n");
        close(iInFileFD);
        return ERROR;
    }

    return NOERROR; /*The file has been uploaded succesfully*/
}

/**
 * Download file from server.
 * 
 * @author Rik Janssen
 */
int cmdDownload(char *ptr_sFilenameServer, char *ptr_sFilenameClient)
{
    int outFileFD = 0, n = 1460, i, iRecvReturn = 0;
    char buf[1460];
    char sRecvBuf[1460];
    char sDownloadCmd[200] = "DOWNLOAD ";

    /*Open or creat file*/
    printf("Creating/Opening file: %s\n", ptr_sFilenameClient);
    if((outFileFD = open(ptr_sFilenameClient, O_WRONLY|O_CREAT, 0644)) == -1)
    {
        perror("error opening or creating file\n");
        return ERROR; //exit this function
    }

    /*set vars/buffers to NULL*/
    for(i = 0; i < 1460; i++)
    {
        buf[i] = 0;
        sRecvBuf[i] = 0;
    }

    /*Send DOWNLOAD cmd*/
    strcat(sDownloadCmd, ptr_sFilenameServer);
    send(iSocketFD, sDownloadCmd, strlen(sDownloadCmd)+1, 0);

    /*Receive return from server*/
    iRecvReturn = recv(iSocketFD, &sRecvBuf, 1460, 0);
    if(iRecvReturn == 0 || iRecvReturn == -1)
    {
        fprintf(stderr, "peer has performed an orderly shutdown or error\n");
        return ERROR;
    }

    if(!strcasecmp(sRecvBuf, "READY"))
    {
        send(iSocketFD, "READY", 6, 0);
        while(n == 1460)
        {
            //server data inlezen en wegschrijven
            if((n = recv(iSocketFD, &buf, 1460, 0))>0)
            {
                printf("receiving %s\n", buf);
                if(write(outFileFD, &buf, n) != n)
                {
                    perror("write error on destination file\n");
                }
                printf("n = %d\n", n);
                bzero(buf, strlen(buf));//BY GINO
            }
        }

        close(outFileFD);
        if(n == -1)
        {
            fprintf(stderr, "download error\n");
        }
        else
        {
            printf("Done!\n");
            return NOERROR;
        }
    }

    return ERROR; //geen goede reactie van server
}
